C128_FreeMemory_EDASS-128_FewSourceCodes

By lived.ch, 15:18 10.05.2024
-------------------------------------------------------------------------------------------------------------
I needed a little distraction from coding. That's the result...!
Everything is also on .d64 floppy {virtual}

Making here some advertising for native Commodore C128 programming in assembler ;-)

The below located source codes and files on .d64 will sure made you curios if you are looking to start with
assembly coding on C128 computer! 
{my start was 2023, November! I am still pure and proud retro C128 assembly greenhorn}
-------------------------------------------------------------------------------------------------------------

Important: This information is not meant for BASIC programming on C128!
	   But only for programming with EDASS-128 on Commodore 128
	
*Native assembly programming directly on C128 is always a huge mystery due to leck of free memory 
for your own lines when assembly environment is installed.

{*= With native, i mean real HW C128 or emulated C128. Ergo, no Cross-Compiler}

Because i prefer native programming, even though people already in '70s,'80s used some kind of hardware
cross-compiler to avoid leck of free memory on the host they were coding for, i made a decision to
start {November 2023} and stay with it and accept all challenges and frustrations of nativer coding ;-)
Last thing a heard was that people used ATARI ST {and many other computers} to code for Commodore C128
{I guess that was probably for Go64!}. They transferred the files using an interface and had no need to
use the fancy 1571 drive, or any floppy drive at all.

Several months ago I tried many assembly languages for C128 and eventually made a final choice to use EDASS-128.
It is occupying a huge portion of free memory and you basically have following main free locations:


Let us start!

-----------------------------------------------------------------------------------------------------------------------
Well, first the OCCUPIED memory by EDASS-128:

   BANK 0		NOTE
0. $03e4 - $03ef	Calling EDASS-128 		
1. $1a00 - $1bff	ROM - Jump Tables* { see further below }
2. $f000 - $feff	Routines in Common Area

   BANK 1	
0. $b400 - $feff	Main Program

   VECTORS
0. IMAIN - $0302	Modified by EDASS-128
1. CLTVEC- $0334	Do not touch or change!
2. SHFVEC- $0336	Do not touch or change!
3. ESCVEC- $0338	Do not touch or change!

And we shouldn't forget the space needed for the source code, labels, comments etc.
That is bringing us to what is available.
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------

AND NOW THE FREE MEMORY LOCATIONS WHICH CAN BE USED BY EDASS-128:


$0B00 - $0bff 	
If NO Datasette is used and also not SFK 2.1 Rev. A3

{However, you can use BASIC 7.0 version of SFK and this location will be free}

$0c00 - $0dff
If NO RS232 Interface is used and also not SFK 2.1 Rev. A3

{ BASIC 7.0 version of SFK is making this location free }
{ you could go up to $fff, if you don't use SPRDEF for sprite definition }
{ that is a lot of room for practicing with assembler }
{ SPRDEF is storing sprite definitions from $0e00 to $0fff }
{ meaning, if you do plan using use sprites, you still have space $0c00 - 0dff }
{ from $1000 Function Keys are defined, so don't go there }
{ that's $0fff + $01 }

$1300 - $19FF
Huge Space below BASIC ($1C01), a bit less than 2KB...

{ note: between $1a00 and $1bff, EDASS-128 is resident }
{ don't 'poke' anything at that locations, UNLESS you'll use EDASS-128 ver. 2 }
{ Main location of EDASS-128 is $1b400 and up, Bank 1 }

$1C00 - $3FFF 	
BASIC RAM is AVAILABLE...

{ but as mentioned already, it's only 11 KB there without graphic screens }
{ However, if you aren't planning BASIC-Assembler cooperation }
{ then there you go, 11KB free space for your assembler code }

Zero Page $00 - $ff	
Almost all is occupied by EDASS-128...

{ can't say what 'almost all' is, couldn't find any info }
{ But if only a few addresses are free, }
{ unused by the system, how much could 'almost all' be? }
{ UPDATE 08.05.2024: $fa, $fb, $fc, $fd are free for personal use in zero page area } 
{ according to examples in EDASS-128 Book }

If you aren't going to use SPRDEF, then there is:
		dec 4791-4853, hex $12B7-$12F5 free  ,062

And that's still not all, there is more:
				     		     ,{ bytes available }		
		dec 	 0673, hex 	 $02a1 Unused,001
	vector,	dec 0786-0787, hex $0312-$0313 Unused,002
		dec 1021-1023, hex $03fd-$03ff Unused,003
		dec 2024-2039, hex $07e8-$07f7 Unused,015

		dec 2048-2559, hex $0800-$09FF Unused,512 
		{ BASIC Runtime Stack (use if no BASIC is used) }

		dec 2622-2623, hex $0a3e-$0a3f Unused,002
		dec 2651-2655, hex $0a5b-$0a5f Unused,005 
		dec 2670-2687, hex $0a6e-$0a7f Unused,018
		dec 	 2736, hex 	 $0ab0 Unused,001
		dec 2746-2751, hex $0aba-$0abf Unused,006
		dec 	 2757, hex 	 $0ac5 Unused,001
		dec 2758-2815, hex $0ac6-$0aff Unused,058
		dec 4590-4607, hex $11ee-$11ff Unused,017
		dec 4862-4863, hex $12FE-$12FF Unused,001
		dec 16416 - 8, hex $4020-$   2 Unused,003
		dec 49200 - 2, hex $C030-$   2 Unused,003 

-----------------------------------------------------------------------------------------------------------------------

VERY IMPORTANT INFO:
If you use GRAPHIC command, the BASIC start pointers are changed and BASIC area is moved to $4000.
GRAPHIC color map {1KB} is starting at $1c00 to $1fff and GRAPHIC area itself is starting at $2000
until $3fff {8KB}.

Now, with EDASS installed, you can't use space above $4000 because EDASS-128 is located there.
That leaves you then only the free areas for your own code as listed above until $19ff.
Why not until $1bff you might say! Well, between *$1a00 - 1bff also EDASS-128 is resident and that 
space of 512 bytes can't be used therefore. 

*However, EDASS-128 is coming in 2 versions and the 2nd one EDASS-128.2.0, can be executed as follows 
run "EDASS-128.2.0". This one gives you free space from $1300 to $1bff {additional 512 bytes}. 

In addition to above listed free locations, there are also some smaller, e.g. 1 - 6 bytes locations.
Sounds small, but those are like pure GOLD!

$02a1, $03fd-$03ff, $0a3e-$0a3f, $0a5b-$0a5f, $0ab0, $0aba-$0abf, $0ac5, $12FE-$12FF, $4020-$4022,
$C030- $C032

And there is also another location which could be used in case you are not going to use SPRDEF, meaning
Sprite Definition Editor. That is: $12B7-$12F5, exactly 62 bytes.

Now, in EDASS-128, like also some other assembly language editors, you can define with asterisk {*} where your
start address is going to be, e.g. *= $1300.
But you can use this also to spread your code to the available free spaces in memory. 


-----------------------------------------------------------------------------------------------------------------------
EXAMPLE PROGRAMS in assembly using EDASS-128 {for C128}
-----------------------------------------------------------------------------------------------------------------------
{ EDASS-128 example 1 }:


example1.asm       -a:0011-a:    -e:

         *=  $1300     ;start address
         .obj m
         .bank 15
;
         lda #$00
         sta $d020
         jsr $1400     ;go to $1400
         ldx #$00
         lda #$00
 draw    sta $2000,x   ;draw 1/2 scr lin
         sta $20a0,x
         inx
         cpx #$a0      ;160 byte
         bne draw
         ldx #$00
         lda #$05      ;green
 color   sta $1c00,x   ;give some color
         inx
         cpx #$28
         bne color
 wait    jsr $ffe4
         cmp #$0d      ;is enter pressed
         beq exit      ;yes, exit.
         jmp wait
 exit    lda #$00      ;leave gfx mode 1
         sta $d8
         rts
;
         *=  $1400     ;move to $1400
;
         lda #$20      ;set graphic
         sta $d8       ;mode 1
         lda #$00
         sta $ff00
         jsr $6b30
         rts


-----------------------------------------------------------------------------------------------------------------------
{ EDASS-128 example 2 }:


This is one way to use it, but more practical way is to set load subroutines in one portions from where
you can then load rest of your code into memory.


example2.asm       -a:0011-a:    -e:

         *=  $1300     ;start address
         .obj m
         .bank 15
;
         jsr $77b3     ;fast mode
         lda #$93      ;clr screen
         jsr $ffd2
;
 setbnk  =   $ff68
 getcfg  =   $ff6b
 setlfs  =   $ffba
 setnam  =   $ffbd
 loadsp  =   $ffd5
 start   =   $0e00     ;sprites
;
 sprflag lda #$00
         cmp #$00
         beq getspr
         bne sprdone
 getspr  jsr loadspr
 sprdone jsr $77c4     ;slow again
         jmp $1500     ;main program
;
         *=  $1400
;
 loadspr ldx #$00      ;bank number
         jsr getcfg    ;mmu-config
         jsr setbnk    ;set bank
         lda #$01      ;logical file
         ldx #$08      ;device address
         ldy #$00      ;secondary addres
         jsr setlfs    ;set config
         lda #$09      ;file lenght
         ldx #<loads   ;low-byte name
         ldy #>loads   ;high-byte name
         jsr setnam    ;set name
         lda #$00      ;load-verify
         ldx #<start   ;low-byte start
         ldy #>start   ;high-byte start
         jmp loadsp    ;load & close
 loads   .text "sprite.bl"
;
         *=  $1500
;
         lda #$01
         sta sprflag+1 ;no more spr load
         sta $d020     ;border color
         sta $d015     ;sprite 1
         sta $12fd     ;bas irq off
 loop    lda #$80
         sta $d000     ;xy=128
         sta $d001
         ldx #$00
 line    lda #$e0
         sta $0400+(12*40),x
         lda #$05
         sta $d800+(12*40),x
         inx
         cpx #$28
         bne line
         jsr $ffe4
         cmp #$0d
         beq basic
         jmp loop
 basic   rts           ;basic


-----------------------------------------------------------------------------------------------------------------------
{ EDASS-128 example 3 }:


If you want to load several files, best way to do it is to have an easy name and have noticed somewhere
what exactly is loaded. E.g. .text '0max' 
Use then branch commands to load exactly what you need without a necessity
to have xyz load routines, one for each file.

1max = load info screen -> $0400 > $05e0, dec  1024 >  1504, 12 lines
2max = load color map	-> $d800 > $d9e0, dec 55296 > 55776, 12 lines
3max = load lived.ch    -> $0608 > $07c0, dec  1544 >  1984, 12 lines {13 - 25, load from $05e0}, middle of the screen
4max = load color map	-> $d800 > $d9e0, dec 55296 > 55776, 12 lines {13 - 25, load from $d9e0}, middle of the screen
5max = load sprites	-> $0e00 > $0fff, dec  3584 >  4095, 12 lines {08 different sprites}
6max = load main code	-> $1500 > ?

How can you do that?
{NOTE: first name is 1max, but it must start with 0max therefore}
{Sure, we could have just jump over the first incrementing, but why would we wanna do that, right ;-)}
This is loading 6 files with very little code.

IMPORTANT INFO:
Files {x}max were saved each individually by using BSAVE command in BASIC direct mode.
You need to be familiar with the address. Not like a pro, but you should know by now that $0400 is the default
screen start address and $d800 is start address of the 40 column color map are.
Sprites are located at $0e00 until $0fff.
{You could have them elsewhere too! All you need to do then is change the pointers in 2040-2047}
{Default is 56 for 2040 = POKE 2040,56}

To save full screen 40 column screen and color:
						bsave"screengfx",b15,p1024top1024+(25*40)
						bsave"screencol",b15,p55296top55296+(25*40)

To save memory location you need, best is to use built-in Machine Language Monitor (ML) and see where your code ends.
To save a location from $1300 to $13aa {where your loading routine is}:
						bsave"startme",b15,p4864top5034

To save your main code starting at $3000 - $3800 you type:
						bsave"main",b15,p12288top79872

Sprites are saved with following addresses. It's 512 bytes {8x 64 bytes = 512 bytes}.
All 8 sprites! {but you can save them also individually}: 
						bsave"mysprites",b15,p3584top3584+(512)	
						
And take a look at the example.


example3.asm       -a:0011-a:    -e:

         *=  $1300     ;start address
         .obj m
         .bank 15
;
         lda #$00
         sta $ff00
;        jsr $77b3     ;fast mode
;
 setbnk  =   $ff68
 getcfg  =   $ff6b
 setlfs  =   $ffba
 setnam  =   $ffbd
 loadsp  =   $ffd5
 start1  =   $0400     ;load screen
 start2  =   $d800     ;load color map
 start3  =   $05e0     ;load lived.ch
 start4  =   $d9e0     ;load colormap
 start5  =   $0e00     ;load sprites
 start6  =   $1500     ;load main prog
;
         jsr loadall   ;l 1max info scrn
         jsr loadall   ;l 2max color map
         jsr loadall   ;l 3max lived.ch
         jsr loadall   ;l 4max color map
         jsr loadall   ;l 5max 8 sprites
         jsr loadall   ;l 6max main code
;
         jsr $77c4     ;slow again
;
         lda #$00      ;resets
         sta max+1     ;for load correct
         lda #$30      ;next time
         sta loads     ;#$30 = 0, ascii
;
         jmp $1500     ;main code
;
 loadall lda #$00      ;exclude
         sta $93       ;loading
         sta $9d       ;searching
         inc max+1
         inc loads     ;increment name
 max     lda #$00      ;counter
         ldx #$00      ;bank number
         jsr getcfg    ;mmu-config
         jsr setbnk    ;set bank
         lda #$01      ;logical file
         ldx #$08      ;device address
         ldy #$00      ;secondary addres
         jsr setlfs    ;set config
         lda #$04      ;file lenght
         ldx #<loads   ;low-byte name
         ldy #>loads   ;high-byte name
         jsr setnam    ;set name
;
         lda max+1     ;read max value
         cmp #$01
         beq getmax1
         cmp #$02
         beq getmax2
         cmp #$03
         beq getmax3
         cmp #$04
         beq getmax4
         cmp #$05
         beq getmax5
         cmp #$06
         beq getmax6
;
 getmax1 lda #$00
         ldx #<start1  ;low-byte  start
         ldy #>start1  ;high-byte start
         jmp charge
example3.asm       -a:0083-a:    -e:
 getmax2 lda #$00
         ldx #<start2
         ldy #>start2
         jmp charge
 getmax3 lda #$00
         ldx #<start3
         ldy #>start3
         jmp charge
 getmax4 lda #$00
         ldx #<start4
         ldy #>start4
         jmp charge
 getmax5 lda #$00
         ldx #<start5
         ldy #>start5
         jmp charge
 getmax6 lda #$00
         ldx #<start6
         ldy #>start6
         jmp charge    ;not needed but..
 charge  jmp loadsp    ;load / close
 loads   .text "0max"
;
         *=  $1500     ;always check if
;                      ;the address is
;                      ;correct!
;
         lda #$00
         sta $d021
         lda #$0e
         sta $d020
         lda #$01
         sta $12fd     ;bas irq off
         lda #$c0      ;msb>255,spr 7,8
         sta $d010
         lda #$ff
         sta $d015     ;sprites on
         ldx #$00
 readcol lda sprcol,x  ;get spr colors
         sta $d027,x
         inx
         cpx #$08
         bne readcol
;
         ldx #$00      ;set sprite pos
 setpos  lda sprpos,x  ;all 8
         sta $d000,x
         inx
         cpx #$10
         bne setpos
;
 loop    jsr $ffe4     ;hit enter to
         cmp #$0d      ;exit
         beq basic
         jmp loop
 basic   rts
;
;
;
 sprcol  .byte $01,$02,$03,$04
         .byte $05,$06,$07,$08
;
;sprites 1-8   xxx yyy position
;
 sprpos  .byte $26,$e4 ;spr1
         .byte $4c,$e4 ;spr2
         .byte $72,$e4 ;....
         .byte $98,$e4
         .byte $be,$e4
         .byte $e4,$e4
         .byte $0b,$e4 ;> 255, $0b,msb
         .byte $31,$e4 ;> 255, $31,msb


-----------------------------------------------------------------------------------------------------------------------
{ EDASS-128 example 4 {REU01.ASM}:


With 12000 bytes a good things can be achieved. That being said...hehe...
I am thankful for the emulators we have nowadays.
Because i can activate REU within 5 seconds and even choose which size i want.

If it is already there, why not make some use out of it!

TED 2.0 is screen based editor and it uses C128 BASIC editor to create tiles. 
Since most of the space i had free is gone i thought why not use REU to make 
screen backups {not saving, just temporary backup}.

I had to peek online a little bit and found a solution here {THANKS!}:
commodore128.mirkosoft.sk/reu.htmld

{This is just a bit different from the original file, available at the address above, because i had to adapt it for my
needs, and that is to have the screen transferred to REU. I'll probably end up with 10 screens, but who knows}

- sys 4864 is writing screen {$0400 - $07e7} data to REU BANK 0, location #$00

- sys 5120 is reading REU data from BANK 0, location #$00 and writing to C128, $0400,
  which is standard VIC screen start area.


reu01.asm       -a:0011-a:    -e:

         *=  $1300     ;sys 4864 / write
         .obj m
         .bank 15
;
;--------------------------------------
;reu data transfer to save the default
;text screen area {commodore c128}
;screen data and screen color transfer
;--------------------------------------
;
;thanks to:
;commodore128.mirkosoft.sk/reu.htmld
;
;i slightly modified this to have
;screen transfer of 1000 byte
;
;
 status  =   $df00
 command =   $df01     ;write=/read=
 c128s   =   $df02     ;source/target
 reubase =   $df04
 tsize   =   $df07
 irqmack =   $df09
 control =   $df0a
;------------------------------------
;
;write from c128 memory to reu memory
;
 recreu  lda #$00
         sta control
;
         lda #$00      ;low screen
         sta c128s     ;
         lda #$04      ;high screen
         sta c128s+1   ;
;
         lda #$00      ;low
         sta reubase
         lda #$00      ;high reu
         sta reubase+1
         lda #$00      ;bank 2
         sta reubase+2
;
         lda #$00      ;trans size low
         sta tsize     ;
         lda #$04      ;high
         sta tsize+1   ;screen 1000 byte
         lda #$90
         sta command
         rts
;
         *=  $1400     ;sys 5120 / read
;
;transfer from reu to c128 memory
;
 readreu lda #$00
         sta control
         lda #$00      ;write to screen
         sta c128s
         lda #$04
         sta c128s+1
;
         lda #$00      ;take data
         sta reubase   ;from $0000
         lda #$00      ;
         sta reubase+1
         lda #$00      ;in reu bank 2
         sta reubase+2
;
         lda #$00      ;transfer size
         sta tsize     ;1000 bytes
         lda #$04      ;or one
         sta tsize+1   ;full
         lda #$91      ;screen
         sta command
         rts


-----------------------------------------------------------------------------------------------------------------------
{ EDASS-128 example 5 }:


This copies all you do on screen, including every color, to REU {you must activate it in VICE}
and then back by using following sys commands:

sys 4864 > transfer from C128 to REU {screen and color map data}
sys 5120 < transfer from REU to C128 {to screen $0400 and color map area $d800, 1000 bytes {each area}, hex $0400} 

example5.asm       -e:0011-a:    -e:

         *=  $1300     ;sys 4864 / write
         .obj m
         .bank 15
;
;--------------------------------------
;reu data transfer to save the default
;text screen area {commodore c128}
;screen data and screen color transfer
;--------------------------------------
;
;thanks to:
;commodore128.mirkosoft.sk/reu.htmld
;
;i slightly modified and corrected
;this to have data transfer of $0400
;bytes and not $1000 bytes! because 
;that is actually 4096 bytes.
;lived.ch, 11.05.2024
;
;
 status  =   $df00
 command =   $df01     ;write=/read=
 c128    =   $df02     ;source/target
 reubase =   $df04
 tsize   =   $df07
 irqmack =   $df09
 control =   $df0a
 screen  =   $0400
 colmap  =   $d800
 reuscr  =   $0000     ;reu screen
 reucol  =   $0400     ;reu color
;--------------------------------------
;
;trans screen c128 > reu bank 0, $0000
;
 recreu  lda #$00
         sta control
         lda #<screen
         sta c128
         lda #>screen
         sta c128+1
         lda #<reuscr  ;$0000
         sta reubase
         lda #>reuscr
         sta reubase+1
         lda #$00      ;reu bank 0
         sta reubase+2
         lda #$00      ;transfer 1000
         sta tsize     ;bytes
         lda #$04
         sta tsize+1
         lda #$90      ;save to reu
         sta command
;        rts
;--------------------------------------
;
;trans colormap c128 > reu bank 0, $0400
;
         lda #$00
         sta control
         lda #<colmap
         sta c128
         lda #>colmap
         sta c128+1
         lda #<reucol  ;$0400
         sta reubase
         lda #>reucol
         sta reubase+1
         lda #$00      ;reu bank 0
         sta reubase+2
         lda #$00      ;transfer 1000
         sta tsize     ;bytes
         lda #$04
         sta tsize+1
         lda #$90      ;save to reu
         sta command
         rts
;
;
         *=  $1400     ;sys 5120 / read
;
;
;transfer from reu to c128 memory
;
 readreu lda #$00
         sta control
         lda #<screen  ;write to screen
         sta c128
         lda #>screen
         sta c128+1
         lda #<reuscr  ;read from reu
         sta reubase   ;$0000
         lda #>reuscr  ;
         sta reubase+1
         lda #$00      ;in reu bank 2
         sta reubase+2
;
         lda #$00      ;transfer size
         sta tsize     ;1000 bytes
         lda #$04      ;
         sta tsize+1   ;
         lda #$91      ;read & transfer
         sta command
;        rts
;
         lda #$00      ;color reu > c128
         sta control
         lda #<colmap  ;write to colmap
         sta c128
         lda #>colmap
         sta c128+1
         lda #<reucol  ;read from reu
         sta reubase   ;$0400
         lda #>reucol
         sta reubase+1
         lda #$00      ;in reu bank 2
         sta reubase+2
;
         lda #$00      ;transfer size
         sta tsize     ;1000 bytes
         lda #$04
         sta tsize+1
         lda #$91      ;read & transfer
         sta command
         rts
-----------------------------------------------------------------------------------------------------------------------
